package main

import (
    "fmt"
    "os"
    "os/signal"
    "syscall"
    "time"

    corev1 "k8s.io/api/core/v1"
    "k8s.io/client-go/informers"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/tools/cache"
    "k8s.io/client-go/tools/clientcmd"
)

func main() {
    // 1. 加载 kubeconfig
    kubeconfig := os.Getenv("KUBECONFIG")
    if kubeconfig == "" {
        kubeconfig = clientcmd.RecommendedHomeFile // 默认 ~/.kube/config
    }

    config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
    if err != nil {
        panic(fmt.Errorf("failed to build config: %v", err))
    }

    // 2. 创建 Kubernetes 客户端
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        panic(fmt.Errorf("failed to create client: %v", err))
    }

    // 3. 创建 SharedInformerFactory（核心组件）
    factory := informers.NewSharedInformerFactoryWithOptions(
        clientset,
        10*time.Minute, // 全量同步间隔
        informers.WithNamespace(""), // 监听所有命名空间
    )

    // 4. 创建 Pod Informer
    podInformer := factory.Core().V1().Pods().Informer()

    // 5. 注册事件处理器
    podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
        AddFunc: func(obj interface{}) {
            pod := obj.(*corev1.Pod)
            fmt.Printf("[ADD] Pod: %s/%s (Phase: %s)\n", 
                pod.Namespace, pod.Name, pod.Status.Phase)
        },
        UpdateFunc: func(oldObj, newObj interface{}) {
            newPod := newObj.(*corev1.Pod)
            oldPod := oldObj.(*corev1.Pod)
            if newPod.ResourceVersion != oldPod.ResourceVersion {
                fmt.Printf("[UPDATE] Pod: %s/%s (Phase: %s)\n",
                    newPod.Namespace, newPod.Name, newPod.Status.Phase)
            }
        },
        DeleteFunc: func(obj interface{}) {
            pod := obj.(*corev1.Pod)
            fmt.Printf("[DELETE] Pod: %s/%s\n", pod.Namespace, pod.Name)
        },
    })

    // 6. 启动 Informer（自动处理连接重试和缓存同步）
    stopCh := make(chan struct{})
    defer close(stopCh)
    factory.Start(stopCh)

    // 7. 等待缓存同步完成
    if !cache.WaitForCacheSync(stopCh, podInformer.HasSynced) {
        panic("Failed to sync cache")
    }
    fmt.Println("Cache synced successfully")

    // 8. 信号处理（优雅退出）
    signalCh := make(chan os.Signal, 1)
    signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM)
    <-signalCh
    fmt.Println("\nReceived termination signal, exiting...")
}
